/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package skaitiniai.metodai.perkeltiesMetodas;

import skaitiniai.metodai.perkeltiesMetodas.exceptions.NetenkinamaGrieztaNelygybeException;
import skaitiniai.metodai.perkeltiesMetodas.exceptions.NetenkinamaNegrieztaNelygybeException;

public class PerkeltiesAlgoritmasImpl implements PerkeltiesAlgoritmasI{
    TriistrizaineMatrica matrica;

    @Override
    public void setMatrica(TriistrizaineMatrica m) throws NetenkinamaGrieztaNelygybeException, NetenkinamaNegrieztaNelygybeException {
        int patikrinimas = MatricosValidatorius.getInstance().patikrintiMatrica(m);
        
        if (patikrinimas >= 0) {
            throw new NetenkinamaNegrieztaNelygybeException("Netenkinama negrieztos istrizaines vyravimo salyga " + (patikrinimas+1) + " eiluteje!!!");
        }
        if (patikrinimas == MatricosValidatorius.NETENKINAMA_GRIEZTA){
            throw new NetenkinamaGrieztaNelygybeException("Netenkinama grieztos istrizaines vyravimo salyga ne vienoje eiluteje!!!");
        }
 
        this.matrica = m;
    }

    @Override
    public double[] apskaiciuotiX()  {
        int n = matrica.getB().length;
        
        double[] X = new double[n];
        double[] C = new double[n];
        double[] D = new double[n];
        n--; // masyvo indeksas yra 1 mazesnis nei ilgis
        C[0] = (-1) * matrica.getC()[0]/matrica.getB()[0];
        D[0] = matrica.getD()[0] / matrica.getB()[0];
        //Tiesiogine eiga
        for (int k = 1; k <= n; k++){
            C[k] = -(1) * matrica.getC()[k] / (matrica.getA()[k] * C[k - 1] + matrica.getB()[k]);
            D[k] = (matrica.getD()[k] - matrica.getA()[k] * D[k-1])/(matrica.getA()[k] * C[k-1] + matrica.getB()[k]);         

        }
        
        
        //Atbuline eiga
        X[n] = D[n];

        for (int k = n - 1; k >= 0; k--){
            X[k] = C[k] * X[k + 1] + D[k];  
        }
        
        return X;
    }
    
}
